x86/altp2m: make sure EPTP_INDEX is up-to-date when enabling #VE
authorGeorge Dunlap <george.dunlap@citrix.com>
Mon, 23 Sep 2019 12:29:37 +0000 (14:29 +0200)
committerJan Beulich <jbeulich@suse.com>
Mon, 23 Sep 2019 12:29:37 +0000 (14:29 +0200)
commit08cb4b93dd898246131791cd8491ae35c5ef8f55
treed8e9eae47f0730cc436122695497b6d9d6b446a7
parent8efcc0d2d3bc3fdc325c0e7c9ec625575e66b805
x86/altp2m: make sure EPTP_INDEX is up-to-date when enabling #VE

vmx_vmexit_handler() assumes that if
SECONDARY_EXEC_ENABLE_VIRT_EXCEPTIONS is set, that the value in
EPTP_INDEX is valid.  Unfortunately, the function which sets this bit
(vmx_vcpu_update_vmfunc_ve) doesn't actually set EPTP_INDEX; it will
only be set the next time vmx_vcpu_update_eptp() is called.

This means that if a vcpu makes a vmexit between these two points, the
EPTP_INDEX it reads will be invalid.  The first time this race happens
for a domain, EPTP_INDEX will most likely be zero, which is the index
for the "host" p2m -- and thus is often correct.  But the second time
this race happens, the value will typically be INVALID_ALTP2M, which
will hit the following BUG:

    BUG_ON(idx >= MAX_ALTP2M);

Worse, if for some reason the current altp2m was *not* `0` during this
window (say, because a toolstack changed the VM to a different view),
then the accounting of active vcpus for an altp2m will be thrown off.

Fix this by always updating EPTP_INDEX to the current altp2m index
when enabling #VE.

Reported-by: Razvan Cojocaru <rcojocaru@bitdefender.com>
Signed-off-by: George Dunlap <george.dunlap@citrix.com>
Reviewed-by: Razvan Cojocaru <rcojocaru@bitdefender.com>
Tested-by: Razvan Cojocaru <rcojocaru@bitdefender.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
master commit: 1dddfff4c39d3db17dfa709b1c57f44e3ed352e3
master date: 2018-08-02 12:12:43 +0200
xen/arch/x86/hvm/vmx/vmx.c